import { NavBar, InfiniteScroll, Popup, Toast } from 'antd-mobile'
import { useHistory, useParams } from 'react-router-dom'
import classNames from 'classnames'
import styles from './index.module.scss'

import Icon from '@/components/Icon'
import CommentItem from './components/CommentItem'
import CommentFooter from './components/CommentFooter'
import { useDispatch, useSelector } from 'react-redux'
import { useEffect, useRef, useState } from 'react'
import {
  addComment,
  followUser,
  getArticleDetail,
  getCommentList
} from '@/store/actions/article'
import { RootState } from '@/types/store'
import dayjs from 'dayjs'
import DOMPurify from 'dompurify'
import hljs from 'highlight.js'
import 'highlight.js/styles/vs2015.css'
import NoComment from './components/NoComment'
import CommentInput from './components/CommentInput'
import CommentReply from './components/CommentReply'
import { Comment } from '@/types/data'

const Article = () => {
  const history = useHistory()

  // 获取动态路由参数
  const params = useParams<{ id: string }>()
  const dispatch = useDispatch()

  // 获取文章详情数据及文章评论数据
  const { info, comment } = useSelector((state: RootState) => state.article)

  // 点击关注
  const onFollowAuthor = async () => {
    await dispatch(followUser(info.aut_id, info.is_followed))
  }

  // 控制评论表单
  const [showCommentForm, setShowCommentForm] = useState(false)

  // 显示回复列表
  const [showReply, setShowReply] = useState({
    visible: false,
    origin: {} as Comment
  })

  // 控制顶部导航栏显示文章作者
  const [showAuthor, setShowAuthor] = useState(false)
  const authorRef = useRef<HTMLDivElement>(null)
  const wrapperRef = useRef<HTMLDivElement>(null)
  const commentRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const wrapDOM = wrapperRef.current!
    const authorDOM = authorRef.current!

    const onScroll = function () {
      const rect = authorDOM.getBoundingClientRect()!
      // console.log(rect.top)
      setShowAuthor(rect.top <= 0)
    }

    wrapDOM.addEventListener('scroll', onScroll)

    return () => {
      wrapDOM.removeEventListener('scroll', onScroll)
    }
  }, [])

  // 页面一加载便请求文章详情及文章评论数据
  useEffect(() => {
    dispatch(getArticleDetail(params.id))
    dispatch(getCommentList(params.id))
  }, [dispatch, params.id])

  // 文章加载后对语法进行高亮
  useEffect(() => {
    // 1.配置highlight.js
    hljs.configure({
      ignoreUnescapedHTML: true // 去除控制台打印的关于非转义字符的警告信息
    })

    // 2. 获取文章内容中所有的 pre 标签
    const els = document.querySelectorAll('.dg-html pre')

    // 3. 执行高亮
    els.forEach((el) => {
      hljs.highlightElement(el as HTMLElement)
    })
  }, [info])

  const renderArticle = () => {
    // 文章详情
    return (
      <div className="wrapper" ref={wrapperRef}>
        <div className="article-wrapper">
          <div className="header">
            <h1 className="title">{info.title}</h1>

            <div className="info">
              <span>{dayjs(info.pubdate).format('YYYY-MM-DD')}</span>
              <span>{info.read_count} 阅读</span>
              <span>{info.comm_count} 评论</span>
            </div>

            <div className="author" ref={authorRef}>
              <img src={info.aut_photo} alt="" />
              <span className="name">{info.aut_name}</span>
              <span
                className={classNames(
                  'follow',
                  info.is_followed ? 'followed' : ''
                )}
                onClick={onFollowAuthor}
              >
                {info.is_followed ? '已关注' : '关注'}
              </span>
            </div>
          </div>

          <div className="content">
            <div
              className="content-html dg-html"
              dangerouslySetInnerHTML={{
                __html: DOMPurify.sanitize(info.content || '')
              }}
            />
            <div className="date">
              发布文章时间：{dayjs(info.pubdate).format('YYYY-MM-DD')}
            </div>
          </div>
        </div>

        <div className="comment" ref={commentRef}>
          <div className="comment-header">
            <span>全部评论（{info.comm_count}）</span>
            <span>{info.like_count} 点赞</span>
          </div>

          <div className="comment-list">
            {info.comm_count === 0 ? (
              <NoComment />
            ) : (
              comment.results?.map((item) => (
                <CommentItem
                  key={item.com_id}
                  type="normal"
                  comment={item}
                  onReply={(comment) => {
                    setShowReply({
                      visible: true,
                      origin: comment
                    })
                  }}
                />
              ))
            )}

            <InfiniteScroll
              hasMore={comment.last_id !== comment.end_id}
              loadMore={async () => {
                await dispatch(getCommentList(params.id, comment.last_id))
              }}
            />
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className={styles.root}>
      <div className="root-wrapper">
        <NavBar
          onBack={() => history.go(-1)}
          right={
            <span>
              <Icon name="icongengduo" />
            </span>
          }
        >
          {showAuthor && (
            <div className="nav-author">
              <img src={info.aut_photo} alt="" />
              <span className="name">{info.aut_name}</span>
              <span
                className={classNames(
                  'follow',
                  info.is_followed ? 'followed' : ''
                )}
                onClick={onFollowAuthor}
              >
                {info.is_followed ? '已关注' : '关注'}
              </span>
            </div>
          )}
        </NavBar>
        {/* 文章详情和评论 */}
        {renderArticle()}

        {/* 底部评论栏 */}
        <CommentFooter
          type="normal"
          info={info}
          onShowComment={() => {
            setShowCommentForm(true)
          }}
          onGotoComment={() => {
            const wrapDOM = wrapperRef.current!
            const commentDOM = commentRef.current!
            const commentPos = commentDOM.offsetTop - 45

            // 在评论列表位置和页面顶部之间切换
            // console.log(Math.ceil(wrapDOM.scrollTop), commentPos)
            wrapDOM.scrollTop =
              Math.ceil(wrapDOM.scrollTop) === commentPos ? 0 : commentPos
          }}
        />
        <Popup visible={showCommentForm} position="right">
          <CommentInput
            onClose={() => {
              setShowCommentForm(false)
            }}
            onPublish={async (content: string) => {
              await dispatch(addComment(params.id, content))
              await dispatch(getArticleDetail(params.id))

              Toast.show({
                icon: 'success',
                content: '发表成功'
              })
            }}
          />
        </Popup>

        <Popup visible={showReply.visible} position="right" destroyOnClose>
          <CommentReply
            origin={showReply.origin}
            onClose={() => {
              setShowReply({
                visible: false,
                origin: showReply.origin as Comment
              })
            }}
          />
        </Popup>
      </div>
    </div>
  )
}

export default Article
